import 'package:any_reader/public.dart';
import 'package:any_reader/views/reader/page_agent.dart';
import 'package:any_reader/views/reader/reader_theme.dart';

import '../provider/export.dart';
import 'export.dart';

class ReaderTheme {
  final Color background;
  final Color text;
  final Color expandBackground;
  final Color expandText;
  final Color expandActive;
  final int type;
  ReaderTheme({
    this.background,
    this.text,
    this.expandBackground,
    this.expandText,
    this.expandActive,
    this.type = 0,
  });
}

class ReaderConfig {
  double fontSize;
  double lineHeight;
  double padding;
  ReaderConfig({this.fontSize, this.lineHeight, this.padding});
}

String kThemeIndex = "kReaderThemeIndex";
String kReaderFrontSize = "kReaderFrontSize";
String kReaderLineHeight = "kReaderLineHeight";
String kReaderPadding = "kReaderPadding";
String kReadeModel = "kReadeModel";

enum ReadMode { empty, scroll }

class ReaderModel extends ViewStateModel {
  ThemeModel themeModel;
  ReaderModel(this.themeModel);
  String bookId;
  String catalogId;
  String num;
  String position;
  Book book;
  int chapterIndex = 0;
  List<Chapter> chapterList = [];
  String currentChapterId = "";
  int pageIndex = 0;
  List<Article> articleList = [new Article(), new Article(), new Article()];
  PageController pageController;
  ReaderTheme theme; //阅读皮肤
  ReadMode readMode;
  ReaderConfig readerConfig;
  bool toolBarStatus = false;
  ScrollController scrollController = new ScrollController();
  bool isLoadingArticle = false;
  void setConfig(name, val, {bool needState = true}) async {
    if (needState) {
      for (int i = 0; i < articleList.length; i++) {
        articleList[i] = initializeContent(articleList[i]);
      }
      notifyListeners();
    }
    MiniStorage.save(name, val);
//    initializeContent
  }

  void onScroll() {
//    pageController.jumpToPage(page);
    var page = pageController.offset / ScreenUtil().setWidth(750);
    var nextArticlePage =
        (articleList[1].pageCount ?? 0) + (articleList[0].pageCount ?? 0);
    if (page >= nextArticlePage) {
      print("到下个章节了");
      chapterList[chapterIndex].local = 1;
      articleList[0] = articleList[1];
      articleList[1] = articleList[2];
      articleList[2] = new Article();
      chapterIndex += 1;
      currentChapterId = articleList[1].catalogId.toString();
      pageController.jumpToPage(articleList[0].pageCount);
      print("articleList[1].nextCatalogId ${articleList[1].nextCatalogId}");
      if (articleList[1].nextCatalogId != null) {
        setContent(2,
            catalogId: articleList[1].nextCatalogId,
            num: articleList[1].nextCatalogNum);
      }
      if (currentChapterId.length < 1 || bookId.length < 1) {
        return;
      }
      DatabaseHelper().updateBook(
        update: {"position": pageIndex, "now": chapterIndex},
        where: "book_id=? ",
        whereArgs: [bookId],
      );
    }
    if (page <= articleList[0].pageCount - 1) {
      print("回到上个章节了");
      articleList[2] = articleList[1];
      articleList[1] = articleList[0];
      articleList[0] = new Article();
      chapterIndex -= 1;
      currentChapterId = articleList[1].catalogId.toString();
      pageController.jumpToPage(articleList[1].pageCount - 1);
      print("articleList[1].preCatalogId ${articleList[1].preCatalogId}");
      if (articleList[1].preCatalogId != null) {
        setContent(0,
            catalogId: articleList[1].preCatalogId,
            num: articleList[1].preCatalogNum);
      }
      if (currentChapterId.length < 1 || bookId.length < 1) {
        return;
      }
      DatabaseHelper().updateBook(
        update: {"position": pageIndex, "now": chapterIndex},
        where: "book_id=?",
        whereArgs: [bookId],
      );
    }
    notifyListeners();
  }

  initData({
    String bookId,
    String catalogId,
    String num,
    String position,
    PageController pageController,
    Function call,
  }) async {
    setBusy(true);
    //初始化加载章节

    this.bookId = bookId;
    this.catalogId = catalogId;
    this.num = num;
    this.position = position;

    if (bookId != null && bookId != "") {
      DatabaseHelper().updateBookLastOpen(bookId);
    }

    initTheme();
    currentChapterId = this.catalogId;
    this.pageController = pageController;
    pageController.addListener(onScroll);
    chapterList = await DatabaseHelper().getAllChapter(bookId);
    book = await DatabaseHelper().findBook(bookId);
    setBusy(false);
    if (chapterList.length == 0) {
      print("********************************************");
      print("*********没有在本地数据库中查询到章节信息，正在获取");
      print("********************************************");
      setBusy(true);
      await updateChapter(
        bookId,
        book.reptileType,
        book.title,
        book.author,
        book.originUrl,
        catalogId,
      );
      setBusy(false);
    }
//    this.position =
//        this.position != '' ? this.position : book.position ?? 0;
    chapterIndex = await findChapterIndex();

    if (call != null) {
      call();
    }
    notifyListeners();

    setContent(1, catalogId: this.catalogId, num: this.num);
  }

  Future<List<Chapter>> updateChapter(String bookId, String reptileType,
      String bookName, String author, String bookUrl, String catalogId) async {
    List<Chapter> list = await ChapterService.findAll(
      bookId: bookId,
      reptileType: reptileType,
      bookName: bookName,
      author: author,
      bookUrl: bookUrl,
    );
    if (list.length > 0) {
      chapterList = list;
      DatabaseHelper().insertChapter(bookId, reptileType, list);
    }
    notifyListeners();
    return list;
  }

  Future<int> findChapterIndex() async {
    print("要查找的Index $currentChapterId");
    for (var index = 0; index < chapterList.length; index++) {
      if (chapterList[index].catalogId == currentChapterId) {
        return Future.value(index);
      }
    }
    return Future.value(0);
  }

  //获取章节了
  setContent(int index,
      {String catalogId,
      String num,
      fromCache: true,
      force: false,
      forceServer: false}) async {
    print("准备获取 catalogId 内容 $catalogId");
    if (index == 1) {
      this.isLoadingArticle = true;
      notifyListeners();
    }
    Article _article;
    if (fromCache == true) {
      //默认从缓存中读取
      _article = await DatabaseHelper().findArticle(bookId, catalogId);
    }
    if (_article == null) {
      _article = await loadData(catalogId, num, forceServer: forceServer);
    }
    if (_article.content == null) {
      this.isLoadingArticle = false;
      notifyListeners();
      return;
    }
    _article = initializeContent(_article);
    articleList[index] = _article;
    if (index == 0 && _article.pageCount > 0) {
      pageController.jumpToPage(_article.pageCount + pageIndex);
    }
    if (index == 1) {
      this.isLoadingArticle = false;
      notifyListeners();
      if ((articleList[0].pageCount == 0 || force) &&
          _article.preCatalogId != "0") {
        print("_article.preChapterId  ${_article.preCatalogId}");
        setContent(0,
            catalogId: _article.preCatalogId, num: _article.preCatalogNum);
      }
      if ((articleList[2].pageCount == 0 || force) &&
          _article.nextCatalogId != "0") {
        print("_article.nextChapterId  ${_article.nextCatalogId}");
        setContent(
          2,
          catalogId: _article.nextCatalogId,
          num: _article.nextCatalogNum,
        );
      }
    }

    notifyListeners();
    if (index == 0) {
      DatabaseHelper().insertArticle(
          bookId,
          catalogId,
          _article.name,
          _article.num,
          _article.type,
          _article.updateTime,
          _article.isReptileTool,
          _article.reptileAddress,
          _article.content);
    }
  }

  findNextChapterId(String chapterId) {
    if (chapterList[chapterList.length - 1].catalogId == chapterId) return "0";
    for (var i = 0; i < chapterList.length; i++) {
      if (chapterList[i].catalogId == chapterId) {
        return chapterList[i + 1].catalogId;
      }
    }
    return "0";
  }

  findPrevChapterId(String chapterId) {
    if (chapterList[0].catalogId == chapterId) return "0";
    for (var i = 0; i < chapterList.length; i++) {
      if (chapterList[i].catalogId == chapterId) {
        return chapterList[i - 1].catalogId;
      }
    }
    return "0";
  }

  Article initializeContent(Article article) {
    double contentHeight = ScreenUtil().setHeight(1334) -
        ScreenUtil().setWidth(100) -
        ScreenUtil().setHeight(20);

    double contentWidth = ScreenUtil().setWidth(750) -
        ScreenUtil().setWidth(readerConfig.padding) * 2;
    if (article.nextCatalogId == "") {
      article.nextCatalogId = findNextChapterId(article.catalogId);
    }
    if (article.preCatalogId == "") {
      article.preCatalogId = findPrevChapterId(article.catalogId);
    }
    article.pageOffsets = ReaderPageAgent.getPageOffsets(
      article.content,
      contentHeight,
      contentWidth,
      ScreenUtil().setSp(readerConfig.fontSize * 2),
      ScreenUtil().setHeight(readerConfig.lineHeight * 2),
      theme.text,
      readMode,
    );
    double _height = 0;
//    print("article.pageOffsets ${article.pageOffsets.length}");
    for (int index = 0; index < article.pageOffsets.length; index++) {
//      print("_height += ${article.pageOffsets[index]['pageHeight']}");
      _height += article.pageOffsets[index]['pageHeight'];
    }
//    print("_height $_height");
    article.pageHeight = _height;
    return article;
  }

  Future<Article> loadData(String chapterId, String num,
      {int retry: 0, forceServer: false}) async {
    Article article = await ReaderService.fetchArticle(
        bookId: bookId,
        catalogId: chapterId,
        num: num,
        forceServer: forceServer);
//    if (article.content == null) {
//      if (retry < 3) {
//        return loadData(chapterId, num, retry: retry + 1);
//      } else {
//        return article;
//      }
//    }
    return article;
  }

  refresh(int index,
      {String catalogId, String catalogNum, forceServer = false}) async {
    print("refresh");
    print(" index $index");
    print(" catalogId $catalogId");
    print(" catalogNum $catalogNum");
    //这里最好使用current
    this.isLoadingArticle = true;
    notifyListeners();
    await setContent(index,
        catalogId: catalogId,
        num: catalogNum,
        forceServer: forceServer,
        fromCache: false);
  }

  //获取上一章
  previousPage() {
    if (articleList[1].preCatalogId == null ||
        articleList[1].preCatalogId == "0") {
      return;
    }
    articleList[2] = articleList[1];
    articleList[1] = articleList[0];
    articleList[0] = new Article();
    notifyListeners();
    chapterIndex -= 1;
    currentChapterId = articleList[1].catalogId.toString();
//    pageController.jumpToPage(articleList[1].pageCount - 1);

    if (readMode == ReadMode.empty) {
      pageController.jumpToPage(articleList[0].pageCount);
    } else {
      scrollController.jumpTo(0);
    }

    if (articleList[1].preCatalogId != null) {
      setContent(0,
          catalogId: articleList[1].preCatalogId,
          num: articleList[1].preCatalogNum);
    }
    if (currentChapterId.length < 1 || bookId.length < 1) {
      return;
    }
    DatabaseHelper().updateBook(
      update: {"position": pageIndex, "now": chapterIndex},
      where: "book_id=?",
      whereArgs: [bookId],
    );
  }

  //获取下一章
  nextPage() {
    if (articleList[1].nextCatalogId == null ||
        articleList[1].nextCatalogId == "0") {
      return;
    }
    chapterList[chapterIndex].local = 1;
    articleList[0] = articleList[1];
    articleList[1] = articleList[2];
    articleList[2] = new Article();
    notifyListeners();
    chapterIndex += 1;
    if (readMode == ReadMode.empty) {
      pageController.jumpToPage(articleList[0].pageCount);
    } else {
      scrollController.jumpTo(0);
    }
    if (articleList[1].nextCatalogId != null) {
      setContent(2,
          catalogId: articleList[1].nextCatalogId,
          num: articleList[1].nextCatalogNum);
    }
    if (currentChapterId.length < 1 || bookId.length < 1) {
      return;
    }
    currentChapterId = articleList[1].catalogId.toString();
    DatabaseHelper().updateBook(
      update: {"position": pageIndex, "now": chapterIndex},
      where: "book_id=?",
      whereArgs: [bookId],
    );
  }

  //
  Future<bool> initTheme() async {
    int themeIndex = (await (MiniStorage.get(kThemeIndex))) ?? 0;
    readMode = (await (MiniStorage.get(kReadeModel)) ?? 2) == 1
        ? ReadMode.empty
        : ReadMode.scroll;
    double fontSize = (await (MiniStorage.get(kReaderFrontSize))) ?? 16;
    double lineHeight = (await (MiniStorage.get(kReaderLineHeight))) ?? 1;
    double padding = (await (MiniStorage.get(kReaderPadding))) ?? 10;
    readerConfig = ReaderConfig(
        fontSize: fontSize, lineHeight: lineHeight, padding: padding);
    theme = themeList[themeIndex];
    notifyListeners();
    return Future.value(true);
  }
}
